package cn.yunyichina.provider.bone.service.impl;

import cn.yunyichina.provider.bone.dao.BedSubscribeDao;
import cn.yunyichina.provider.bone.entity.BedSubscribe;
import cn.yunyichina.provider.bone.utils.BoneMsgUtils;
import cn.yunyichina.provider.framework.common.PKGenerator;
import cn.yunyichina.provider.framework.dubbo.service.BaseService;
import cn.yunyichina.provider.framework.dubbo.service.MessageService;
import cn.yunyichina.provider.framework.page.PageInfo;
import cn.yunyichina.provider.iface.entity.base.OrgUserOpenidVo;
import cn.yunyichina.provider.iface.entity.common.Response;
import cn.yunyichina.utils.commons.DateUtils;
import cn.yunyichina.utils.convert.JsonUtils;
import com.alibaba.dubbo.common.utils.StringUtils;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.log4j.Log4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Created by zhuxp on 2018/1/17.
 * 床位预约管理
 * @param
 * @Descrition
 */
@Service
@Log4j
public class BedSubcribeServiceImpl {

    private final String BED_SUBCRIBE_AWAIT_TEMPLATE_CODE ="TMP60001";
    private final String BED_SUBCRIBE_COMPLTE_TEMPLATE_CODE ="TMP60002";
    private final String BED_SUBCRIBE_REFUSE_TEMPLATE_CODE ="TMP60003";
    private final String MSG_DOCTOR_APP_CODE ="yytb294d158a26b11e6";

    @Autowired
    private BedSubscribeDao bedSubscribeDao;

    /**
     * yyt.bone.bed.subcribe.list
     * 床位预约列表查询
     * @param data
     * @return
     */
    public Response listBedSubcribe(String data){
        log.info("查询床位预约记录列表入参：");
        Response response = new Response();
        try {
            BedSubscribe bedSubscribe = JsonUtils.parseObject(data,BedSubscribe.class);
            JSONObject jsonObject = JsonUtils.parseObject(data,JSONObject.class);
            String pageSize = jsonObject.getString("page_size");
            String pageNum = jsonObject.getString("page_num");
            //分页查询
            if(pageNum !=null && pageSize !=null){
                long count = bedSubscribeDao.selectCount(bedSubscribe);
                PageInfo pageInfo = new PageInfo();
                pageInfo.setTotal(count);
                pageInfo.setPageNum(Integer.valueOf(pageNum));
                pageInfo.setPageSize(Integer.valueOf(pageSize));
                pageInfo.setPages((pageInfo.getTotal().intValue() + pageInfo.getPageSize() - 1) / pageInfo.getPageSize());
                List<BedSubscribe> bedSubscribes = bedSubscribeDao.select(bedSubscribe,pageInfo);
                Map<String,Object> map = new HashMap<>();
                map.put("pageInfo",pageInfo);
                map.put("list",bedSubscribes);
                response.setResultCodeAndMessageAndResult(Response.SUCCESS_CODE,Response.SUCCESS_MESSAGE,JsonUtils.toJsonString(map));
            }else{
                //列表查询
                List<BedSubscribe> lists =bedSubscribeDao.select(bedSubscribe);
                response.setResultCodeAndMessageAndResult(Response.SUCCESS_CODE,Response.SUCCESS_MESSAGE,JsonUtils.toJsonString(lists));
            }
        }catch (Exception e){
            log.info("查询床位预约记录异常!"+e);
            e.printStackTrace();
            response.setResultCodeAndMessage(Response.FAILURE_CODE,"查询床位预约记录异常!");
        }
        return response;
    }

    public Response queryBedSubcribeHistory(String data){
        log.info("查询床位预约历史记录列表入参：");
        Response response = new Response();
        try {
            BedSubscribe bedSubscribe = JsonUtils.parseObject(data,BedSubscribe.class);
            bedSubscribe.setStatus(2);
            List<BedSubscribe> lists =bedSubscribeDao.queryBedSubcribeHistory(bedSubscribe);
            response.setResultCodeAndMessageAndResult(Response.SUCCESS_CODE,Response.SUCCESS_MESSAGE,JsonUtils.toJsonString(lists));
        }catch (Exception e){
            log.info("查询床位预约历史记录列表异常!"+e);
            e.printStackTrace();
            response.setResultCodeAndMessage(Response.FAILURE_CODE,"查询床位预约历史记录列表异常!");
        }
        return response;
    }

    /**
     * 查询医生床位预约数量
     * yyt.bone.bed.subcribe.count.query
     * @param data
     * @return
     */
    public Response queryBedSubcribeCount(String data){
       log.info("查询医生预约数量详情入参："+data);
        Response response = new Response();
        try {
            BedSubscribe bedSubscribe = JsonUtils.parseObject(data,BedSubscribe.class);
            //状态 1 排队中  2 已完成
            bedSubscribe.setStatus(1);
            long countWait = bedSubscribeDao.selectCount(bedSubscribe);
            bedSubscribe.setStatus(2);
            long countComplete = bedSubscribeDao.selectCount(bedSubscribe);
            Map<String,Object> resultMap = new HashMap<>();
            resultMap.put("waitCount",countWait);
            resultMap.put("completeCount",countComplete);
            response.setResultCodeAndMessageAndResult(Response.SUCCESS_CODE,Response.SUCCESS_MESSAGE, JsonUtils.toJsonString(resultMap));
        }catch (Exception e){
            log.info("查询医生预约数量详情入参!"+e);
            e.printStackTrace();
            response.setResultCodeAndMessage(Response.FAILURE_CODE,"查询床位预约记录异常!");
        }
        return response;
    }

    /**
     * yyt.bone.bed.subcribe.delete
     * 床位预约删除
     * @param data
     * @return
     */
    public Response deleteBedSubcribe(String data){
        log.info("删除预约记录入参："+data);
        Response response = new Response();
        try {
            BedSubscribe bedSubscribe =JsonUtils.parseObject(data,BedSubscribe.class);
            if(StringUtils.isBlank(bedSubscribe.getId())){
                response.setResultCodeAndMessage(Response.FAILURE_CODE,"预约记录id不能为空！");
                return response;
            }
            BedSubscribe entity  = bedSubscribeDao.selectById(bedSubscribe.getId());
            if(entity == null){
                response.setResultCodeAndMessage(Response.FAILURE_CODE,"预约记录id有误！");
                return response;
            }
            bedSubscribeDao.selectById(bedSubscribe.getId());
            response.setResultCodeAndMessage(Response.SUCCESS_CODE,Response.SUCCESS_MESSAGE);
        }catch (Exception e){
            log.error("删除预约记录异常！"+e);
            e.printStackTrace();
            response.setResultCodeAndMessage(Response.FAILURE_CODE,"删除预约记录异常！");
        }
        return  response;
    }

    /**
     * yyt.bone.bed.subcribe.insert
     * 新增预约记录
     * @param data
     * @return
     */
    public Response insertBedSubcribe(String data){
        log.info("新增预约记录入参:"+data);
        Response response = new Response();
        try {
            BedSubscribe bedSubscribe = JsonUtils.parseObject(data,BedSubscribe.class);
            if(StringUtils.isBlank(bedSubscribe.getUserId())||StringUtils.isBlank(bedSubscribe.getDoctorId())||StringUtils.isBlank(bedSubscribe.getUserOpenId())){
                response.setResultCodeAndMessage(Response.FAILURE_CODE,"医生id或患者id或患者openid不能为空！");
                return response;
            }
            BedSubscribe entity = new BedSubscribe();
            entity.setDoctorId(bedSubscribe.getDoctorId());
            entity.setUserId(bedSubscribe.getUserId());
            entity.setStatus(0);
            List<BedSubscribe> entitys = bedSubscribeDao.select(entity);
            if(!entitys.isEmpty()){
                response.setResultCodeAndMessage(Response.FAILURE_CODE,"不能重复预约同一医生！");
                return  response;
            }else {
                entity.setStatus(1);
                List<BedSubscribe> beds= bedSubscribeDao.select(entity);
                if(!beds.isEmpty()){
                    response.setResultCodeAndMessage(Response.FAILURE_CODE,"不能重复预约同一医生！");
                    return  response;
                }
            }
            bedSubscribe.setId(PKGenerator.generateId());
            bedSubscribe.setStatus(0);
            bedSubscribe.setCreateTime(DateUtils.getDateTimeStr());
            bedSubscribe.setUpdateTime(DateUtils.getDateTimeStr());
            bedSubscribeDao.insert(bedSubscribe);
            response.setResultCodeAndMessageAndResult(Response.SUCCESS_CODE,Response.SUCCESS_MESSAGE,JsonUtils.toJsonString(bedSubscribe));
        }catch (Exception e){
            log.error("新增预约记录异常!"+e);
            e.printStackTrace();
            response.setResultCodeAndMessage(Response.FAILURE_CODE,"新增预约记录异常!");
        }
        return response;
    }

    /**
     *  更新预约状态未已拒绝
     *  yyt.bone.bed.subcribe.refuse
     * @param data
     * @return
     */
    public Response refuseBedSubcribe(String data){
        log.info("拒绝预约入参："+data);
        Response response = new Response();
        try {
            BedSubscribe bedSubscribe = JsonUtils.parseObject(data,BedSubscribe.class);
            BedSubscribe entity = bedSubscribeDao.selectById(bedSubscribe.getId());
            if(entity == null){
                response.setResultCodeAndMessage(Response.FAILURE_CODE,"预约记录id有误!");
                return response;
            }
            if(StringUtils.isBlank(bedSubscribe.getCancleReason())){
                response.setResultCodeAndMessage(Response.FAILURE_CODE,"拒绝预约理由不能为空!");
                return response;
            }
            if(entity.getStatus()==1){
                /*更新的预约状态为 排队中  刷新排队数量*/
                updateWaitSubcribe(entity);
            }
            //预约状态（0：已提交   1：排队中  2：已完成  3：已取消）
            entity.setStatus(3);
            entity.setWaitNum(null);
            entity.setCancleReason(bedSubscribe.getCancleReason());
            entity.setUpdateTime(DateUtils.getDateTimeStr());
            bedSubscribeDao.update(entity);
            sendMessage(entity);
            response.setResultCodeAndMessage(Response.SUCCESS_CODE,Response.SUCCESS_MESSAGE);
        }catch (Exception e){
            log.error("拒绝预约异常"+e);
            e.printStackTrace();
            response.setResultCodeAndMessage(Response.FAILURE_CODE,"拒绝预约异常");
        }
        return response;
    }

    private void updateWaitSubcribe(BedSubscribe entity) {
        BedSubscribe bedSubscribe =  new BedSubscribe();
        bedSubscribe.setDoctorId(entity.getDoctorId());
        bedSubscribe.setStatus(1);
        List<BedSubscribe> lists = bedSubscribeDao.select(bedSubscribe);
        for(BedSubscribe bed:lists){
            if(!bed.getId().equals(entity.getId())){
                bed.setWaitNum(bed.getWaitNum()-1);
                bedSubscribeDao.update(bed);
            }
        }
    }

    /**
     *  更新预约状态为完成
     *  yyt.bone.bed.subcribe.complete
     * @param data
     * @return
     */
    public Response completeBedSubcribe(String data){
        log.info("完成预约入参："+data);
        Response response = new Response();
        try {
            BedSubscribe bedSubscribe = JsonUtils.parseObject(data,BedSubscribe.class);
            BedSubscribe entity = bedSubscribeDao.selectById(bedSubscribe.getId());
            if(entity == null){
                response.setResultCodeAndMessage(Response.FAILURE_CODE,"预约记录id有误!");
                return response;
            }
            if(StringUtils.isBlank(bedSubscribe.getInHospitalTime())||StringUtils.isBlank(bedSubscribe.getInHospitalSite())){
                response.setResultCodeAndMessage(Response.FAILURE_CODE,"入院时间或入院地址不能为空!");
                return response;
            }
            if(entity.getStatus()==1){
                /*更新的预约状态为 排队中  刷新排队数量*/
                updateWaitSubcribe(entity);
            }
            //预约状态（0：已提交   1：排队中  2：已完成  3：已取消）
            entity.setStatus(2);
            entity.setWaitNum(null);
            entity.setInHospitalSite(bedSubscribe.getInHospitalSite());
            entity.setInHospitalTime(bedSubscribe.getInHospitalTime());
            entity.setUpdateTime(DateUtils.getDateTimeStr());
            bedSubscribeDao.update(entity);
            sendMessage(entity);
            response.setResultCodeAndMessage(Response.SUCCESS_CODE,Response.SUCCESS_MESSAGE);
        }catch (Exception e){
            log.error("完成预约异常"+e);
            e.printStackTrace();
            response.setResultCodeAndMessage(Response.FAILURE_CODE,"完成预约异常");
        }
        return response;
    }

    /**
     *  更新预约状态未排队中
     *  yyt.bone.bed.subcribe.await
     * @param data
     * @return
     */
    public Response awaitBedSubcribe(String data){
        log.info("发送预约给专家入参："+data);
        Response response = new Response();
        try {
            BedSubscribe bedSubscribe = JsonUtils.parseObject(data,BedSubscribe.class);
            BedSubscribe entity = bedSubscribeDao.selectById(bedSubscribe.getId());
            if(entity == null){
                response.setResultCodeAndMessage(Response.FAILURE_CODE,"预约记录id有误!");
                return response;
            }
            /* 查询正在排队人数*/
            BedSubscribe bsc = new BedSubscribe();
            bsc.setDoctorId(entity.getDoctorId());
            bsc.setStatus(1);
            List<BedSubscribe> lists = bedSubscribeDao.select(bsc);
            //预约状态（0：已提交   1：排队中  2：已完成  3：已取消）
            entity.setStatus(1);
            entity.setWaitNum(lists.size()+1);
            entity.setUpdateTime(DateUtils.getDateTimeStr());
            bedSubscribeDao.update(entity);
            sendMessage(entity);
            response.setResultCodeAndMessage(Response.SUCCESS_CODE,Response.SUCCESS_MESSAGE);
        }catch (Exception e){
            log.error("发送预约给专家异常"+e);
            e.printStackTrace();
            response.setResultCodeAndMessage(Response.FAILURE_CODE,"发送预约给专家异常");
        }
        return response;
    }

    /**
     *  预约消息推送
     * @param bedSubscribe
     */
    private void sendMessage(BedSubscribe bedSubscribe) {
        log.info("推送消息入参："+bedSubscribe);
        //微信通知参数 配置
        String firstMsg = "";
        String templateCode = "";
        String remark ="如有相关疑问，可联系客服电话020-85600747。";
        String actionUrl = "";
        String method = "yyt.message.msg.template.send";
        String messageContent ="";
        String orgCode ="rykj";

        //短信通知 参数配置
        Map<String, String> msgContent = new HashMap<>();
        Map<String,Object> pushMap = new HashMap<>();

        Integer status  = bedSubscribe.getStatus();
        switch (status){
            case 1:
                //推送 排队中消息  后台点击发送 给专家
                firstMsg ="您好，"+bedSubscribe.getDoctorName()+"医生，有患者向您预约住院床位，请点击查看处理。";
                templateCode = "60001";
                actionUrl = BoneMsgUtils.queryActionUrl(BED_SUBCRIBE_AWAIT_TEMPLATE_CODE)+"&app_code="+MSG_DOCTOR_APP_CODE+"&id="+bedSubscribe.getId();

                //获取医生信息
                /****根据医生id 获取医生的appid ****/
                Map<String,Object> map = new HashMap<>();
                map.put("org_user_id",bedSubscribe.getDoctorId());
                map.put("app_code",MSG_DOCTOR_APP_CODE);
                Response rep = BaseService.callHumpFromInternal("yyt.base.orgopenid.get",JsonUtils.toJsonString(map));
                List<OrgUserOpenidVo> list = JSON.parseArray(rep.getResult(),OrgUserOpenidVo.class);
                OrgUserOpenidVo vo = list.get(0);

                messageContent = "{\"user_type\":\"2\",\"platform_type\":\"" + 1+ "\",\"org_app_code\":\"" + MSG_DOCTOR_APP_CODE +  "\",\"org_code\":\"" + orgCode + "\",\"to_user\":\""
                        + vo.getOpenId()
                        + "\",\"template_code\":\"" + templateCode
                        + "\",\"url\":\"" + actionUrl +
                        "\",\"msg_content\":\"{\\\"first\\\": \\\"" +
                        firstMsg +
                        "\\\"," +
                        "\\\"keyword1\\\": \\\""
                        + bedSubscribe.getUserName()
                        + "\\\",\\\"keyword2\\\": \\\""
                        + bedSubscribe.getDoctorName()
                        + "\\\",\\\"keyword3\\\": \\\""
                        + bedSubscribe.getDiseaseName()
                        + "\\\",\\\"keyword4\\\": \\\""
                        + bedSubscribe.getCreateTime()
                        + "\\\",\\\"keyword5\\\": \\\""
                        + bedSubscribe.getWaitNum()
                        + "\\\",\\\"remark\\\": \\\"" +
                        remark
                        + "\\\"}\"}";

                //短信参数
                msgContent.put("doctor_name",bedSubscribe.getDoctorName());
                msgContent.put("user_name",bedSubscribe.getUserName());
                pushMap.put("to_user", bedSubscribe.getDoctorMobile());
                pushMap.put("msg_type", 101);
                pushMap.put("msg_content",msgContent);
                break;
            case 2:
                //推送 已完成消息 发送 通知患者入院
                firstMsg ="您好，"+bedSubscribe.getUserName()+"，医生已为您安排床位，请按照住院时间前往住院。";
                templateCode = "60002";
                actionUrl = BoneMsgUtils.queryActionUrl(BED_SUBCRIBE_COMPLTE_TEMPLATE_CODE)+"&app_code="+bedSubscribe.getOrgAppCode()+"&id="+bedSubscribe.getId()+"&stepNum=3";
                messageContent = "{\"user_type\":\"2\",\"platform_type\":\"" + 1+ "\",\"org_app_code\":\"" + bedSubscribe.getOrgAppCode() +  "\",\"org_code\":\"" +orgCode+ "\",\"to_user\":\""
                        + bedSubscribe.getUserOpenId()
                        + "\",\"template_code\":\"" + templateCode
                        + "\",\"url\":\"" + actionUrl +
                        "\",\"msg_content\":\"{\\\"first\\\": \\\"" +
                        firstMsg +
                        "\\\"," +
                        "\\\"keyword1\\\": \\\""
                        + bedSubscribe.getUserName()
                        + "\\\",\\\"keyword2\\\": \\\""
                        + bedSubscribe.getDoctorName()
                        + "\\\",\\\"keyword3\\\": \\\""
                        + bedSubscribe.getDiseaseName()
                        + "\\\",\\\"keyword4\\\": \\\""
                        + bedSubscribe.getInHospitalTime()
                        + "\\\",\\\"keyword5\\\": \\\""
                        +bedSubscribe.getInHospitalSite()
                        + "\\\",\\\"remark\\\": \\\"" +
                        remark
                        + "\\\"}\"}";

                //短信参数
                msgContent.put("user_name",bedSubscribe.getUserName());
                msgContent.put("in_hospital_time",bedSubscribe.getInHospitalTime());
                msgContent.put("in_hospital_site",bedSubscribe.getInHospitalSite());
                pushMap.put("to_user", bedSubscribe.getUserMobile());
                pushMap.put("msg_type", 102);
                pushMap.put("msg_content",msgContent);

                break;
            case 3:
                //推送 已拒绝消息  发送 预约取消通知
                firstMsg ="您好，"+bedSubscribe.getUserName()+"，您预约的"+bedSubscribe.getDoctorName()+"医生的床位申请已取消，原因是："+bedSubscribe.getCancleReason();
                templateCode = "60003";
                actionUrl = BoneMsgUtils.queryActionUrl(BED_SUBCRIBE_REFUSE_TEMPLATE_CODE)+"&app_code="+bedSubscribe.getOrgAppCode()+"&id="+bedSubscribe.getId()+"&stepNum=1";
                messageContent = "{\"user_type\":\"2\",\"platform_type\":\"" + 1+ "\",\"org_app_code\":\"" + bedSubscribe.getOrgAppCode() +  "\",\"org_code\":\"" + orgCode+ "\",\"to_user\":\""
                        + bedSubscribe.getUserOpenId()
                        + "\",\"template_code\":\"" + templateCode
                        + "\",\"url\":\"" + actionUrl +
                        "\",\"msg_content\":\"{\\\"first\\\": \\\"" +
                        firstMsg +
                        "\\\"," +
                        "\\\"keyword1\\\": \\\""
                        + bedSubscribe.getUserName()
                        + "\\\",\\\"keyword2\\\": \\\""
                        + bedSubscribe.getDoctorName()
                        + "\\\",\\\"keyword3\\\": \\\""
                        + bedSubscribe.getDiseaseName()
                        + "\\\",\\\"keyword4\\\": \\\""
                        + bedSubscribe.getCreateTime()
                        + "\\\",\\\"remark\\\": \\\"" +
                        remark
                        + "\\\"}\"}";

                //短信参数
                msgContent.put("doctor_name",bedSubscribe.getDoctorName());
                msgContent.put("user_name",bedSubscribe.getUserName());
                msgContent.put("cancle_reason",bedSubscribe.getCancleReason());
                pushMap.put("to_user", bedSubscribe.getUserMobile());
                pushMap.put("msg_type", 103);
                pushMap.put("msg_content",msgContent);
                break;
            default:
                log.error("床位预约状态有误"+bedSubscribe);
                break;
        }

        log.info("床位预约微信通知消息推送入参："+JSON.toJSONString(messageContent));
        Response messageResponse = MessageService.callHumpFromInternal(method, messageContent);
        log.info("床位预约微信通知消息推送出参："+JSON.toJSONString(messageResponse));
        if (!"0".equals(messageResponse.getResultCode())){
            log.info("sendMessage  床位预约微信通知消息推送失败");
        }else {
            log.info("sendMessage  床位预约微信通知消息推送成功");
        }

        log.info("床位预约短信消息推送入参："+JsonUtils.toJsonString(pushMap));
        MessageService.callUnderlineFromInternal("yyt.message.msg.sms.send", JsonUtils.toJsonString(pushMap));
    }
}
